package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Autowired
    private ContentServiceClient contentServiceClient;

    @Autowired
    private XcChooseCourseMapper xcChooseCourseMapper;

    @Autowired
    private XcCourseTablesMapper xcCourseTablesMapper;

    /**
     * 添加选课
     *
     * @param userId   用户id
     * @param courseId 课程id
     * @return XcChooseCourseDto
     */
    @Transactional
    @Override
    public XcChooseCourseDto addChooseCourse(String userId, Long courseId) {
        // 根据课程id，远程调用，获取课程信息
        CoursePublish coursePublish = contentServiceClient.getCoursepublish(courseId);
        if (coursePublish == null) throw new XueChengPlusException("课程信息不存在");

        // 课程类型（免费：201000、收费：201001）
        String charge = coursePublish.getCharge();

        XcChooseCourse xcChooseCourse;
        XcCourseTables xcCourseTables;

        if ("201000".equals(charge)) {
            log.info("添加免费课程..");
            // 添加免费课程到选课记录表
            xcChooseCourse = addFreeToChooseCourse(userId, courseId, coursePublish);
            // 添加到课程表
            xcCourseTables = addCourseTables(userId, courseId, xcChooseCourse, coursePublish);
        } else {
            log.info("添加收费课程");
            // 添加到选课记录表
            xcChooseCourse = addChargeToChooseCourse(userId, courseId, coursePublish);
        }

        // 构建返回参数
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(xcChooseCourse, xcChooseCourseDto);
        // 获取学生的学习资格
        XcCourseTablesDto courseTablesDto = getLearnStatus(userId, courseId);
        xcChooseCourseDto.setLearnStatus(courseTablesDto.learnStatus);
        return xcChooseCourseDto;

    }

    /**
     * 获取用户的学习资格
     *
     * @param userId   用户id
     * @param courseId 课程id
     * @return 学习资格状态：查询数据字典 [{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
     */
    @Override
    public XcCourseTablesDto getLearnStatus(String userId, Long courseId) {
        // 返回结果对象
        XcCourseTablesDto courseTablesDto = new XcCourseTablesDto();
        // 1. 查询我的课程表
        XcCourseTables courseTables = xcCourseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>()
                .eq(XcCourseTables::getUserId, userId)
                .eq(XcCourseTables::getCourseId, courseId));

        // 2. 未查到，返回一个状态码为"702002"的对象
        if (courseTables == null) {
            courseTablesDto = new XcCourseTablesDto();
            courseTablesDto.setLearnStatus("702002"); // 没有选课或选课后没有支付
            return courseTablesDto;
        }
        // 3. 查到了，判断是否过期
        boolean isExpires = LocalDateTime.now().isAfter(courseTables.getValidtimeEnd());
        // 3.1 已过期，返回状态码为"702003"的对象
        if (isExpires) {
            BeanUtils.copyProperties(courseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702003"); // 已过期需要申请续期或重新支付
            return courseTablesDto;
        }
        // 3.2 未过期，返回状态码为"702001"的对象
        else {
            BeanUtils.copyProperties(courseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702001"); // 正常学习
            return courseTablesDto;
        }
    }


    /**
     * 查询课程表
     *
     * @param params 课程表查询参数
     * @return PageResult<XcCourseTables>
     */
    @Override
    public PageResult<XcCourseTables> myCourseTable(MyCourseTableParams params) {
        return null;
    }


    /**
     * 添加到课程表
     *
     * @param userId         用户id
     * @param courseId       课程id
     * @param xcChooseCourse 选课记录
     * @param coursePublish  课程信息
     */
    private XcCourseTables addCourseTables(String userId, Long courseId, XcChooseCourse xcChooseCourse, CoursePublish coursePublish) {
        // 是否选课成功
        String status = xcChooseCourse.getStatus();
        if (!"701001".equals(status)) {
            XueChengPlusException.cast("选课未成功，无法添加到课程表");
        }

        // 判断是否已在课程表中
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(XcCourseTables::getUserId, userId)
                .eq(XcCourseTables::getCompanyId, coursePublish.getCompanyId())
                .eq(XcCourseTables::getCourseId, courseId);
        XcCourseTables selected = xcCourseTablesMapper.selectOne(queryWrapper);
        if (selected != null) return selected;

        // 添加到课程表
        XcCourseTables xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse, xcCourseTables);
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId());

        int courseTablesInserted = xcCourseTablesMapper.insert(xcCourseTables);
        if (courseTablesInserted != 1) throw new XueChengPlusException("添加到课程表失败");
        return xcCourseTables;
    }


    /**
     * 添加免费课程到选课记录表
     *
     * @param userId        用户id
     * @param courseId      课程id
     * @param coursePublish 课程信息
     * @return XcChooseCourse
     */
    @NotNull
    private XcChooseCourse addFreeToChooseCourse(String userId, Long courseId, CoursePublish coursePublish) {
        // 机构id
        Long companyId = coursePublish.getCompanyId();
        // 课程名称
        String courseName = coursePublish.getName();
        // 课程价格
        Float coursePrice = coursePublish.getPrice();

        // 判断该用户是否已经添加了这门课到选课表
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCompanyId, companyId)
                .eq(XcChooseCourse::getCourseId, courseId);
        XcChooseCourse selected = xcChooseCourseMapper.selectOne(queryWrapper);
        if (selected != null) return selected;

        // 添加到选课记录表
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(courseId);
        xcChooseCourse.setCourseName(courseName);
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(companyId);
        xcChooseCourse.setOrderType("700001"); // 免费课程
        xcChooseCourse.setCoursePrice(coursePrice);
        xcChooseCourse.setValidDays(365);
        xcChooseCourse.setStatus("701001"); // 选课成功
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusYears(1));

        int chooseCourseInserted = xcChooseCourseMapper.insert(xcChooseCourse);
        if (chooseCourseInserted != 1) throw new XueChengPlusException("选课记录插入失败");
        return xcChooseCourse;
    }


    /**
     * 添加收费课程到选课记录表
     *
     * @param userId        用户id
     * @param courseId      课程id
     * @param coursePublish 课程信息
     * @return XcChooseCourse
     */
    @NotNull
    private XcChooseCourse addChargeToChooseCourse(String userId, Long courseId, CoursePublish coursePublish) {
        // 机构id
        Long companyId = coursePublish.getCompanyId();
        // 课程名称
        String courseName = coursePublish.getName();
        // 课程价格
        Float coursePrice = coursePublish.getPrice();

        // 判断该用户是否已经添加了这门课到选课表
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(XcChooseCourse::getUserId, userId)
                .eq(XcChooseCourse::getCompanyId, companyId)
                .eq(XcChooseCourse::getCourseId, courseId);
        XcChooseCourse selected = xcChooseCourseMapper.selectOne(queryWrapper);
        if (selected != null) return selected;

        // 添加到选课记录表
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(courseId);
        xcChooseCourse.setCourseName(courseName);
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(companyId);
        xcChooseCourse.setOrderType("700002"); // 收费课程
        xcChooseCourse.setCoursePrice(coursePrice);
        xcChooseCourse.setValidDays(365);
        xcChooseCourse.setStatus("701002"); // 待支付
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusYears(1));

        int chooseCourseInserted = xcChooseCourseMapper.insert(xcChooseCourse);
        if (chooseCourseInserted != 1) throw new XueChengPlusException("选课记录插入失败");
        return xcChooseCourse;
    }

}
